package com.liveinstars.im.api.impl;

import com.alibaba.fastjson.JSON;
import com.baidu.unbiz.easymapper.MapperFactory;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.liveinstars.api.dto.BatchImGetUserReq;
import com.liveinstars.api.dto.ImGetUserInfo;
import com.liveinstars.api.facade.BadWordsApi;
import com.liveinstars.api.facade.ImUserCentreApi;
import com.liveinstars.api.im.vo.*;
import com.liveinstars.im.common.dto.ChatGroupDTO;
import com.liveinstars.im.common.enums.IMExceptionEnum;
import com.liveinstars.im.common.enums.NoticeMessageTypeEnum;
import com.liveinstars.im.common.enums.PassThroughMessageTypeEnum;
import com.liveinstars.im.core.service.ChatGroupService;
import com.liveinstars.im.core.service.FriendsService;
import com.liveinstars.im.core.service.MessageService;
import com.liveinstars.im.core.service.TodoService;
import com.liveinstars.im.corebean.NoticeMessage;
import com.liveinstars.im.domain.dao.model.ChatGroup;
import com.liveinstars.im.domain.dao.model.ChatGroupMember;
import com.liveinstars.im.domain.dao.model.Todo;
import com.liveinstars.im.domain.manager.ChatGroupManager;
import com.liveinstars.im.domain.manager.ChatGroupMemberManager;
import com.liveinstars.im.domain.manager.FriendsManager;
import com.liveinstars.im.entity.*;
import com.liveinstars.api.im.ChatGroupApiService;
import com.liveinstars.api.im.query.ChatGroupQuery;
import com.liveinstars.im.api.MsgGeneratorService;
import com.liveinstars.im.api.NotifyData;
import com.liveinstars.im.common.enums.ChatGroupTypeEnum;
import com.liveinstars.im.corebean.MsgHelper;
import com.onepiece.shipelves.common.Result;
import com.onepiece.shipelves.common.enums.SystemExceptionEnum;
import com.onepiece.shipelves.common.exception.QuHuiRuntimeException;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ChatGroupApiServiceApiImpl implements ChatGroupApiService {

    private static final Logger LOGGER = LoggerFactory.getLogger(IMUserApiServiceApiImpl.class);

    @Autowired
    private ChatGroupMemberManager chatGroupMemberManager;

    @Autowired
    private ChatGroupManager chatGroupManager;

    @Autowired
    private ChatGroupService chatGroupService;

    @Autowired
    private TodoService todoService;

    @Autowired
    private FriendsService friendsService;

    @Autowired
    private FriendsManager friendsManager;

    @Autowired
    private BadWordsApi badWordsApi;

    @Autowired
    private MsgGeneratorService msgGeneratorService;

    @Autowired
    private ImUserCentreApi imUserCentreApi;

    @Autowired
    private MessageService messageService;

    @Override
    public Result<ChatGroupRecordVO> createChatGroup(String name, Long userId, String users, String desc, Integer type, Integer user_level, String logo, Integer interestId) {
        Result<ChatGroupRecordVO> result = new Result<>();
        if (StringUtils.isEmpty(name)) {
            throw new QuHuiRuntimeException(IMExceptionEnum.CHAT_GROUP_NAME_IS_EMPTY);
        }

        if (badWordsApi.hasBadWords(name + " " + desc, true)) {
            throw new QuHuiRuntimeException(IMExceptionEnum.BAD_WORDS_ERROR);
        }

        ImGetUserInfo userInfo = imUserCentreApi.imGetUserInfo(userId);
        if (userInfo == null || userInfo.getUid() < 1) {
            throw new QuHuiRuntimeException(IMExceptionEnum.USER_IS_NOT_EXIST);
        }

//        ChatGroupQuery chatGroupQuery = new ChatGroupQuery();
//        chatGroupQuery.setChatGroupName(name);
//        List<ChatGroup> list = chatGroupManager.listByQuery(chatGroupQuery);
//        if (CollectionUtils.isNotEmpty(list)) {
//            throw new QuHuiRuntimeException(IMExceptionEnum.CHAT_GROUP_NAME_REPEAT);
//        }

//        Integer count = chatGroupManager.countCreateChatGroupByUserId(userId);
//        //开放圈子创建数
//        if (count > 0) {
//            throw new QuHuiRuntimeException(IMExceptionEnum.CHAT_GROUP_CREATE_ONLY_ONE);
//        }
        ChatGroup chatGroup = new ChatGroup();
        chatGroup.setName(name);
        chatGroup.setCreateById(userId);
        chatGroup.setGroupType(ChatGroupTypeEnum.CHAT_CIRCLE.getValue());
        chatGroup.setDescription(desc);
        chatGroup.setAuthRule(1);
        chatGroup.setUserLevel(user_level);
        chatGroup.setBigClassId(type);
        chatGroup.setGroupLogo(logo);
        chatGroup.setInterestId(interestId);
        ChatGroupDTO dto = new ChatGroupDTO(chatGroup);
        List<ChatGroupMember> memberList = Lists.newArrayList();
        List<Long> userIdList = Lists.newArrayList();
        if (StringUtils.isNotEmpty(users)) {
            String[] userIds = users.split("_");
            if (userIds.length > 200) {
                throw new QuHuiRuntimeException(IMExceptionEnum.CHAT_GROUP_JOIN_LIMIT);
            }
            if (userIds != null && userIds.length > 0) {
                for (String id : userIds) {
                    userIdList.add(Long.valueOf(id));
                }
            }
        }
        userIdList.add(userId);
        BatchImGetUserReq req = new BatchImGetUserReq();
        req.setUids(userIdList);
        com.onepiece.shipelves.common.Result<List<ImGetUserInfo>> listResult = imUserCentreApi.batchImGetUserInfo(req);
        if (listResult.getCode().equals(com.onepiece.shipelves.common.Result.SUCCESS)) {
            for (ImGetUserInfo user : listResult.getData()) {
                ChatGroupMember chatGroupMember = new ChatGroupMember();
                chatGroupMember.setUserId(user.getUid());
                chatGroupMember.setRemarkName(user.getUserName());
                chatGroupMember.setGroupType(ChatGroupTypeEnum.CHAT_CIRCLE.getValue());
                memberList.add(chatGroupMember);
            }
            dto.setMemberList(memberList);
            chatGroupService.createChatGroupWithMember(dto);
            result.setData(dto.chatGroupTransToChatGroupRecordVO());
            return result;
        } else {
            throw new QuHuiRuntimeException(IMExceptionEnum.CHAT_GROUP_NAME_IS_EMPTY);
        }


    }


    @Override
    public Result<ChatGroupRecordVO> updateChatGroup(Long chatGroupId, String name, Long userId, String desc, String logo, Integer user_level, Integer authRule) {
        Result<ChatGroupRecordVO> result = new Result<>();
        if (StringUtils.isNotEmpty(name) || StringUtils.isNotEmpty(desc)) {
            if (badWordsApi.hasBadWords(name + " " + desc, true)) {
                result = IMExceptionEnum.BAD_WORDS_ERROR.createResult();
                return result;
            }
        }
        ChatGroup cg = chatGroupManager.getById(chatGroupId);
        if (cg != null && cg.getCreateById().equals(userId)) {
            if (!StringUtils.isEmpty(name)) {
                cg.setName(name);
            }
            if (!StringUtils.isEmpty(logo)) {
                cg.setGroupLogo(logo);
            }
            if (!StringUtils.isEmpty(desc)) {
                cg.setDescription(desc);
            }
            if (user_level != null) {
                cg.setUserLevel(user_level);
            }
            if (authRule != null) {
                cg.setAuthRule(authRule);
            }
            chatGroupManager.updateById(cg);
            ChatGroupDTO dto = new ChatGroupDTO(cg);
            result.setData(dto.chatGroupTransToChatGroupRecordVO());
        } else {
            result = SystemExceptionEnum.ILLEGAL_REQUEST_PARAM.createResult();
        }

        return result;
    }

    @Override
    public Result<NoticeVO> getNotice(Long chatGroupId) {
        Result<NoticeVO> result = new Result<>();
        return result;
    }

    @Override
    public String shieldChatGroup(Long chatGroupId, Long userId, Long shieldUserId, Integer shieldTime) {
        Result<ChatGroupMember> result = new Result<>();
        ChatGroup chatGroup = chatGroupManager.getById(chatGroupId);
        if (chatGroup != null && (chatGroup.getCreateById().equals(userId) || chatGroup.getManager1Id().equals(userId) || chatGroup.getManager2Id().equals(userId))) {
            //管理员不能禁言别的管理员
            if ((chatGroup.getCreateById().equals(shieldUserId) || chatGroup.getManager1Id().equals(shieldUserId) || chatGroup.getManager2Id().equals(shieldUserId))) {
                result = IMExceptionEnum.CHAT_GROUP_MANAGER_CAN_NOT_SHIELD.createResult();
                return JSON.toJSONString(result);
            }
            ChatGroupMember groupMember = chatGroupMemberManager.getChatGroupMemberByGroupIdAndUserId(chatGroupId, shieldUserId);
            if (groupMember != null) {
                groupMember.setShield(!groupMember.getShield());
                int shieldToTime;
                if (shieldTime == null || "0".equals(shieldTime)) {
                    shieldToTime = (int) LocalDateTime.now().plusYears(99).atZone(ZoneId.systemDefault()).toEpochSecond();
                } else {
                    shieldToTime = (int) LocalDateTime.now().plusSeconds(shieldTime).atZone(ZoneId.systemDefault()).toEpochSecond();
                }
                groupMember.setShieldTime(shieldToTime);
                chatGroupMemberManager.updateById(groupMember);
                result.setData(groupMember);
                return JSON.toJSONString(result);
            } else {
                result = IMExceptionEnum.USER_IS_NOT_EXIST.createResult();
                return JSON.toJSONString(result);
            }
        } else {
            result = SystemExceptionEnum.ILLEGAL_REQUEST_PARAM.createResult();
            return JSON.toJSONString(result);
        }

    }


    @Override
    public String noDisturbChatGroup(Long chatGroupId, Long userId) {
        Result<ChatGroupMember> result = new Result<>();
        ChatGroupMember groupMember = chatGroupMemberManager.getChatGroupMemberByGroupIdAndUserId(chatGroupId, userId);
        if (groupMember != null) {
            groupMember.setNoDisturbing(!groupMember.getNoDisturbing());
            chatGroupMemberManager.updateById(groupMember);
            result.setData(groupMember);
        } else {
            result = IMExceptionEnum.CHAT_GROUP_MANAGER_CAN_NOT_SHIELD.createResult();

        }
        return JSON.toJSONString(result);
    }


    /**
     * 传userid多返回是否屏蔽信息
     *
     * @param chatGroupId
     * @param userId
     * @return
     */
    @Override
    public String getChatGroup(Long chatGroupId, Long userId) {
        Result<ChatGroupP2> result = new Result<>();
        if (chatGroupId != null && chatGroupId != 0) {
            ChatGroup chatGroup = chatGroupManager.getById(chatGroupId);

            if (chatGroup == null) {
                result = IMExceptionEnum.CHAT_GROUP_IS_NOT_EXIST.createResult();
                return JSON.toJSONString(result);
            }
            List<Long> groupIdList = Lists.newArrayList();
            groupIdList.add(chatGroupId);
            Map<Long, Integer> chatGroupMemberCountMap = chatGroupMemberManager.mapMemberCountByChatGroupIdList(groupIdList);
            ChatGroupP2 chatGroupP2 = MapperFactory.getCopyByRefMapper().mapClass(ChatGroup.class, ChatGroupP2.class).register()
                    .map(chatGroup, ChatGroupP2.class);
            chatGroupP2.setUserCount(chatGroupMemberCountMap.get(chatGroupId));
            if (userId != null && userId != 0) {
                ChatGroupMember chatGroupMember = chatGroupMemberManager.getChatGroupMemberByGroupIdAndUserId(chatGroupId, userId);
                if (chatGroupMember != null) {
                    chatGroupP2.setShield(chatGroupMember.getShield());
                    chatGroupP2.setNoDisturbing(chatGroupMember.getNoDisturbing());
                    chatGroupP2.setMeIn(true);
                }
            }
            result.setData(chatGroupP2);
        } else {
            result = SystemExceptionEnum.ILLEGAL_REQUEST_PARAM.createResult();
        }
        return JSON.toJSONString(result);
    }


    @Override
    public String listHotChatGroup(Long userId) {
        Result<List<ChatGroupP1>> result = new Result<>();
        if (userId == null) {
            result = SystemExceptionEnum.ILLEGAL_REQUEST_PARAM.createResult();
        } else {
            List<ChatGroupP1> chatGroupP1s = Lists.newArrayList();
            ChatGroupQuery chatGroupQuery = new ChatGroupQuery();
            chatGroupQuery.setHot(1);
            List<ChatGroup> chatGroupList = chatGroupManager.listByQuery(chatGroupQuery);
            if (CollectionUtils.isNotEmpty(chatGroupList)) {
                chatGroupP1s = makeChatGroupP1List(userId, chatGroupList);
            }
            result.setData(chatGroupP1s);
        }
        return JSON.toJSONString(result);
    }

    @Override
    public String getChatGroupList(Long userId, Integer groupType, Integer groupPage, Integer groupCount) {
        Result<List<ChatGroupP1>> result = new Result<>();
        groupType = groupType != null ? groupType : 1;
        groupPage = groupPage != null ? groupPage : 1;
        groupCount = groupCount != null ? groupCount : 20;
        ChatGroupQuery chatGroupQuery = new ChatGroupQuery();
        chatGroupQuery.setBigClassId(groupType);
        chatGroupQuery.setPageNum(groupPage);
        chatGroupQuery.setPageSize(groupCount);
        Page<ChatGroup> page = chatGroupManager.pageByQuery(chatGroupQuery);
        List<ChatGroup> chatGroupList = page.getRecords();
        if (CollectionUtils.isNotEmpty(chatGroupList)) {
            List<ChatGroupP1> chatGroupP1List = makeChatGroupP1List(userId, chatGroupList);
            result.setData(chatGroupP1List);
        } else {
            result = IMExceptionEnum.CHAT_GROUP_IS_NOT_EXIST.createResult();
        }
        return JSON.toJSONString(result);
    }

    private List<ChatGroupP1> makeChatGroupP1List(Long userId, List<ChatGroup> chatGroupList) {
        List<Long> chatGroupIdList = chatGroupList.stream().map(ChatGroup::getId).collect(Collectors.toList());
        Map<Long, Integer> userCount = chatGroupMemberManager.mapMemberCountByChatGroupIdList(chatGroupIdList);
        List<ChatGroupMember> memberList = chatGroupMemberManager.listByUserIdAndGroupType(userId, ChatGroupTypeEnum.CHAT_CIRCLE.getValue());
        HashMap<Long, ChatGroupMember> groupMemberMap = Maps.newHashMap();
        List<Long> myChatGroupIds = new ArrayList<>();
        memberList.forEach(chatGroupMember -> {
            myChatGroupIds.add(chatGroupMember.getChatGroupId());
            groupMemberMap.put(chatGroupMember.getChatGroupId(), chatGroupMember);
        });
        MapperFactory.getCopyByRefMapper().mapClass(ChatGroup.class, ChatGroupP1.class).register();
        List<ChatGroupP1> chatGroupP1List = chatGroupList.stream().map(p -> MapperFactory.getCopyByRefMapper().map(p,
                ChatGroupP1.class)).collect(Collectors.toList());
        for (ChatGroupP1 chatGroup : chatGroupP1List) {
            chatGroup.setUserCount(userCount.get(chatGroup.getId()));
            chatGroup.setMeIn(myChatGroupIds.contains(chatGroup.getId()));
        }
        return chatGroupP1List;
    }


    @Override
    public String getChatGroupByCreateUid(Long userId) {
        Result<List<ChatGroup>> result = new Result<>();
        List<ChatGroup> list = chatGroupManager.listByCreateUserId(userId);
        if (CollectionUtils.isNotEmpty(list)) {
            result.setData(list);
        } else {
            result = IMExceptionEnum.CHAT_GROUP_IS_NOT_EXIST.createResult();
        }
        return JSON.toJSONString(result);
    }

    @Override
    public String getChatGroupByUid(Long userId) {
        Result<List<ChatGroupP1>> result = new Result<>();
        List<ChatGroupMember> chatGroupMemberList = chatGroupMemberManager.listByUserIdAndGroupType(userId, 0);
        if (CollectionUtils.isNotEmpty(chatGroupMemberList)) {
            List<Long> chatGroupIdList = Lists.newArrayList();
            HashMap<Long, ChatGroupMember> groupMemberMap = Maps.newHashMap();
            chatGroupMemberList.forEach(chatGroupMember -> {
                chatGroupIdList.add(chatGroupMember.getChatGroupId());
                groupMemberMap.put(chatGroupMember.getChatGroupId(), chatGroupMember);
            });
            List<ChatGroup> chatGroupList = chatGroupManager.listByIds(chatGroupIdList);
            Map<Long, Integer> chatGroupMemberCountMap = chatGroupMemberManager.mapMemberCountByChatGroupIdList(chatGroupIdList);
            if (CollectionUtils.isNotEmpty(chatGroupList)) {
                MapperFactory.getCopyByRefMapper().mapClass(ChatGroup.class, ChatGroupP1.class).register();
                List<ChatGroupP1> chatGroupP1List = chatGroupList.stream().map(p -> MapperFactory.getCopyByRefMapper().map(p,
                        ChatGroupP1.class)).collect(Collectors.toList());
                for (ChatGroupP1 chatGroup : chatGroupP1List) {
                    chatGroup.setUserCount(chatGroupMemberCountMap.get(chatGroup.getId()));
                    chatGroup.setShield(groupMemberMap.get(chatGroup.getId()).getShield());
                    chatGroup.setNoDisturbing(groupMemberMap.get(chatGroup.getId()).getNoDisturbing());
                }
                result.setData(chatGroupP1List);
            } else {
                result = IMExceptionEnum.CHAT_GROUP_IS_NOT_EXIST.createResult();
            }
        } else {
            result = IMExceptionEnum.CHAT_GROUP_IS_NOT_EXIST.createResult();
        }
        return JSON.toJSONString(result);
    }

    @Override
    public List<ChatGroupDto> getChatGroupListByUid(Long userId) {
        List<ChatGroupMember> chatGroupMemberList = chatGroupMemberManager.listByUserIdAndGroupType(userId, 0);
        if (CollectionUtils.isNotEmpty(chatGroupMemberList)) {
            List<Long> chatGroupIdList = Lists.newArrayList();
            chatGroupMemberList.forEach(chatGroupMember -> {
                chatGroupIdList.add(chatGroupMember.getChatGroupId());
            });
            List<ChatGroup> chatGroupList = chatGroupManager.listByIds(chatGroupIdList);
            if (CollectionUtils.isNotEmpty(chatGroupList)) {
                MapperFactory.getCopyByRefMapper().mapClass(ChatGroup.class, ChatGroupDto.class).register();
                List<ChatGroupDto> chatGroupP1List = chatGroupList.stream().map(p -> MapperFactory.getCopyByRefMapper().map(p,
                        ChatGroupDto.class)).collect(Collectors.toList());
                return chatGroupP1List;
            } else {
            }
        } else {
        }
        return Collections.emptyList();
    }

    /**
     * 离开和解散圈子
     *
     * @param chatGroupId
     * @param userId
     * @return
     */
    @Override
    public String leaveChatGroup(Long chatGroupId, Long userId) {
        Result<ChatGroupDetailVO> result = new Result<>();
        ChatGroup chatGroup = chatGroupManager.getById(chatGroupId);
        ChatGroupDTO dto = new ChatGroupDTO(chatGroup);
        ChatGroupDetailVO vo = dto.chatGroupTransToChatGroupDetailVO();
        if (chatGroup != null) {
            if (chatGroup.getCreateById().equals(userId)) {
                msgGeneratorService.sendNotifyMessage(new NotifyData(userId, 0L, chatGroup.getName() + "管理员已离开，圈子解散！", chatGroupId));
                chatGroupMemberManager.deleteMemberByChatGroupId(chatGroupId);
                chatGroupManager.deleteById(chatGroupId);
            } else {
                chatGroupMemberManager.deleteMemberByChatGroupIdAndUserId(chatGroupId, userId);
            }
            result.setData(vo);
        } else {
            result = IMExceptionEnum.CHAT_GROUP_IS_NOT_EXIST.createResult();

        }
        return JSON.toJSONString(result);
    }


    @Override
    public String dissolveChatGroup(Long chatGroupId, Long userId) {
        Result<ChatGroupDetailVO> result = new Result<>();
        String message = "";
        boolean success = true;
        ChatGroup chatGroup = chatGroupManager.getById(chatGroupId);
        ChatGroupDTO dto = new ChatGroupDTO(chatGroup);
        ChatGroupDetailVO vo = dto.chatGroupTransToChatGroupDetailVO();
        if (chatGroup == null) {
            result = IMExceptionEnum.CHAT_GROUP_IS_NOT_EXIST.createResult();
        } else {
            if (chatGroup.getCreateById().equals(userId)) {
                msgGeneratorService.sendNotifyMessage(new NotifyData(userId, 0L, chatGroup.getName() + "已解散！", chatGroupId));
                chatGroupMemberManager.deleteMemberByChatGroupId(chatGroupId);
                chatGroupManager.deleteById(chatGroupId);
                result.setData(vo);
            } else {
                result = IMExceptionEnum.CHAT_GROUP_DISBAND_PERMISSION_DENIED.createResult();
            }
        }
        return JSON.toJSONString(result);
    }

    @Override
    public String kickOutChatGroup(Long chatGroupId, Long userId, String kickWho) {
        Result<ChatGroupDetailVO> result = new Result<>();
        String message = "";
        boolean success = true;

        //判断用户是不是圈子的管理员
        ChatGroup chatGroup = chatGroupManager.getById(chatGroupId);
        ChatGroupDTO dto = new ChatGroupDTO(chatGroup);
        ChatGroupDetailVO vo = dto.chatGroupTransToChatGroupDetailVO();
        if (chatGroup == null) {
            result = IMExceptionEnum.CHAT_GROUP_IS_NOT_EXIST.createResult();
        } else {
            if ((chatGroup.getCreateById() != null && chatGroup.getCreateById().equals(userId))) {
                ImGetUserInfo userInfo = imUserCentreApi.imGetUserInfo(chatGroup.getCreateById());
                String[] userIds = kickWho.split("_");
                if (userIds.length > 0) {
                    for (String id : userIds) {
                        Long uid = Long.valueOf(id);
                        if (uid > 0) {
                            msgGeneratorService.sendNotifyMessage(new NotifyData(userId, uid
                                    , "你被" + userInfo.getUserName() + "踢出圈子" + chatGroup.getName() + "!"
                                    , chatGroupId, true));
                            // 推送删除群组通知
                            Map<String, Long> data = Maps.newHashMap();
                            data.put("group_id", chatGroup.getId());
                            Msg.Message noticeMessage = MsgHelper.newNoticeMessage(NoticeMessageTypeEnum.REMOVE_CHAT_GROUP.getValue(), 0, JSON.toJSONString(data));
                            msgGeneratorService.sendRoamingMessage(Long.valueOf(id), PassThroughMessageTypeEnum.USER, noticeMessage);
                            chatGroupMemberManager.deleteMemberByChatGroupIdAndUserId(chatGroupId, uid);
                        }
                    }
                    result.setData(vo);
                } else {
                    result = IMExceptionEnum.CHAT_GROUP_LACK_OPERATION_USER.createResult();
                }
            } else {
                result = IMExceptionEnum.CHAT_GROUP_OPERATION_PERMISSION_DENIED.createResult();
            }
        }
        return JSON.toJSONString(result);
    }


    @Override
    public String getChatGroupMember(Long chatGroupId, Long userId) {
        Result<List<ChatGroupMemberP0>> result = new Result<>();
        ChatGroup chatGroup = chatGroupManager.getById(chatGroupId);
        if (chatGroup == null || chatGroup.getId() < 1) {
            result = IMExceptionEnum.CHAT_GROUP_IS_NOT_EXIST.createResult();
        } else {
            List<ChatGroupMember> memberList = chatGroupMemberManager.listMemberByChatGroupId(chatGroupId);
            MapperFactory.getCopyByRefMapper().mapClass(ChatGroupMember.class, ChatGroupMemberP0.class).register();
            List<ChatGroupMemberP0> list = memberList.stream().map(p -> MapperFactory.getCopyByRefMapper().map(p,
                    ChatGroupMemberP0.class)).collect(Collectors.toList());
            if (list.size() > 0) {
                List<Long> userIdList = Lists.newArrayList();
                Map<Long, ImGetUserInfo> userMap = Maps.newHashMap();
                memberList.forEach(member -> userIdList.add(member.getUserId()));
                if (CollectionUtils.isNotEmpty(userIdList)) {
                    BatchImGetUserReq req = new BatchImGetUserReq();
                    req.setUids(userIdList);
                    Result<List<ImGetUserInfo>> listResult = imUserCentreApi.batchImGetUserInfo(req);
                    if (listResult.getCode().equals(Result.SUCCESS)) {
                        listResult.getData().forEach(userInfo -> userMap.put(userInfo.getUid(), userInfo));
                    }
                }
                for (ChatGroupMemberP0 memberP0 : list) {
                    if (userMap.containsKey(memberP0.getUserId())) {
                        ImGetUserInfo userInfo = userMap.get(memberP0.getUserId());
                        memberP0.setName(userInfo.getUserName());
                        memberP0.setLogo(userInfo.getLogo());
                        memberP0.setDate(userInfo.getRegdate().toString());
                        memberP0.setGroupId(userInfo.getGroupId());
                    }
                    //添加等级名称
                    memberP0.setGroupName(ChatGroup.UserLevel.getUserLevel(memberP0.getGroupId()).getValue());
                }
                result.setData(list);
            } else {
                result = IMExceptionEnum.CHAT_GROUP_MEMBER_IS_NOT_EXIST.createResult();
            }
        }
        return JSON.toJSONString(result);
    }

    @Override
    public String joinChatGroup(Long chatGroupId, Long userId, String reqMsg) {
        Result<ChatGroupDetailVO> result = new Result<>();
        String message = "";
        boolean success = true;
        ImGetUserInfo userInfo = imUserCentreApi.imGetUserInfo(userId);
        if (userInfo == null || userInfo.getUid() < 1) {
            result = IMExceptionEnum.USER_IS_NOT_EXIST.createResult();
            return JSON.toJSONString(result);
        }
        ChatGroup chatGroup = chatGroupManager.getById(chatGroupId);
        ChatGroupDTO dto = new ChatGroupDTO(chatGroup);
        ChatGroupDetailVO vo = dto.chatGroupTransToChatGroupDetailVO();
        if (chatGroup == null || chatGroup.getId() < 1) {
            result = IMExceptionEnum.CHAT_GROUP_IS_NOT_EXIST.createResult();
            return JSON.toJSONString(result);
        }

        int count = chatGroupMemberManager.countByChatGroupId(chatGroupId);
        if (count > 200) {
            result = IMExceptionEnum.CHAT_GROUP_JOIN_LIMIT.createResult();
            return JSON.toJSONString(result);
        }

        boolean matchLevel = ChatGroup.UserLevel.matchLevel(userInfo.getGroupId(), chatGroup.getUserLevel());
        if (!matchLevel) {
            result = IMExceptionEnum.CHAT_GROUP_JOIN_LEVEL_NOT_ALLOW.createResult();
            return JSON.toJSONString(result);
        }

        String requestMsg = "用户 " + userInfo.getUserName() + " 请求加入群 " + chatGroup.getName();
        //判断是否需要等级要求，和是否符合 1-加群需要审核， 0-直接进群
        if (chatGroup.getAuthRule() == 1) {

            ChatGroupMember member = chatGroupMemberManager.getChatGroupMemberByGroupIdAndUserId(chatGroupId, userId);

            if (member != null) {
                result = IMExceptionEnum.CHAT_GROUP_JOIN_USER_IS_EXIST.createResult();
                return JSON.toJSONString(result);
            }


            //代办事项添加
            Todo lastTodo = todoService.getLastTodoByGroupId(userId, chatGroup.getCreateById(), Todo.TODO_TYPE_JOIN_GROUP, chatGroupId);
            if (lastTodo != null && !lastTodo.getComplete()) {
                result = IMExceptionEnum.CHAT_GROUP_JOIN_TODO_IS_EXIST.createResult();
                return JSON.toJSONString(result);
            }
            Todo todo = new Todo();
            todo.setUserId(chatGroup.getCreateById());
            todo.setComplete(false);
            todo.setCreateDate(LocalDateTime.now().atZone(ZoneId.systemDefault()).toEpochSecond());
            todo.setFromId(userId);
            todo.setGroupId(chatGroup.getId());
            todo.setSubject(requestMsg);
            todo.setRequestMsg(reqMsg);
            todo.setType(Todo.TODO_TYPE_JOIN_GROUP);
            todoService.add(todo);
            msgGeneratorService.sendTodoMessage(todo, chatGroup.getCreateById());
        } else {
            List<ChatGroupMember> memberList = Lists.newArrayList();
            ChatGroupMember chatGroupMember = new ChatGroupMember();
            chatGroupMember.setGroupType(chatGroup.getGroupType());
            chatGroupMember.setUserId(userInfo.getUid());
            chatGroupMember.setChatGroupId(chatGroup.getId());
            memberList.add(chatGroupMember);
            chatGroupMemberManager.batchSaveMember(memberList, chatGroup.getId());
            vo.setIsMeIn(true);
        }
        result.setData(vo);
        return JSON.toJSONString(result);
    }

    @Override
    public Result<Boolean> isHasGroupCreate(Long userId) {
        Result<Boolean> result = new Result();
        result.setData(true);
        int count = chatGroupManager.countCreateChatGroupByUserId(userId);
        if (!(count > 0)) {
            result.setData(false);
        }
        return result;
    }

    @Override
    public Boolean makeFriend(Long friendId, Long userId) {
        friendsService.makeFriends(friendId, userId, 1);

        sendMessageAndNotice(friendId, userId);
        sendMessageAndNotice(userId, friendId);
        return true;
    }

    private void sendMessageAndNotice(Long friendId, Long userId) {
        ChatMessage chatMessage = new ChatMessage(friendId, userId, UUID.randomUUID().toString(),
                ChatMessage.STATUS_SEND, ChatMessage.MSG_TYPE_UU, "互相点赞为好友！",
                true, (int) LocalDateTime.now().atZone(ZoneId.systemDefault()).toEpochSecond(),
                2, 0L);
        chatMessage.setType(ChatMessage.TYPE_SEND);
        chatMessage.setId(messageService.getMsgId());
        try {

            messageService.sendMessage(chatMessage);
            Map<String, Long> data = Maps.newHashMap();
            data.put("user_id", friendId);
            Msg.Message noticeMessage = MsgHelper.newNoticeMessage(NoticeMessageTypeEnum.ADD_FRIEND.getValue(), 0, JSON.toJSONString(data));
            msgGeneratorService.sendRoamingMessage(userId, PassThroughMessageTypeEnum.USER, noticeMessage);
        } catch (Exception e) {
            LOGGER.error("makefriend error: {}", e.getMessage(), e);
        }
    }

    @Override
    public Boolean isFriend(Long userId, Long myId) {
        Boolean isFriend = friendsService.isFriends(userId, myId, 1);
        return isFriend;
    }

    /**
     * 发送通知消息
     * @param messageVO
     * @return
     */
    @Override
    public Boolean sendMessage(NoticeMessageVO messageVO) {
        NotifyData notifyData = new NotifyData(messageVO.getUserId(), messageVO.getToId(), messageVO.getContent(), messageVO.getChatGroupId(), messageVO.isOnlyOne());
        LOGGER.info("create activity sendmessage: {} {}", messageVO, notifyData);
        msgGeneratorService.sendNotifyMessage(notifyData);
        return true;
    }
}
